package main

import "fmt"

func main() {
	// example 1
	// var m map[string]int
	// fmt.Println(m == nil) //true
	// m["key1"] = 1         //panic: assignment to entry in nil map

	// example 2
	// var m1 map[string]int = map[string]int{}
	// m2 := map[string]int{}
	// var m3 map[string]int
	// fmt.Println(m3)
	// m1["k1"] = 1
	// m2["k2"] = 2
	// m3["k3"] = 3

	// fmt.Println(m1) // map[k1:1]
	// fmt.Println(m2) // map[k2:2]

	// example 3
	// m1 := map[int][]string{
	// 	1: {"v1-1", "v1-2"},
	// 	3: {"v3-1", "v3-2", "v3-3"},
	// 	4: {"v4-1"},
	// }
	// fmt.Println(m1)

	// type Position struct {
	// 	x int
	// 	y int
	// }

	// m2 := map[Position]string{
	// 	{1, 1}: "a",
	// 	{2, 2}: "b",
	// }
	// fmt.Println(m2)

	// example 4
	// m1 := make(map[int]string)
	// m2 := make(map[int]string, 4)
	// fmt.Println(m1)
	// fmt.Println(m2)

	// example 5

	// m1 := map[int]string{1: "v1", 5: "v5"}
	// m1[2] = "v2"
	// m1[5] = "c5"
	// fmt.Println(m1)

	//  example 6
	// m1 := map[int]string{1: "v1", 2: "v2"}
	// fmt.Println(len(m1)) // 2
	// m1[3] = "v3"
	// fmt.Println(len(m1)) // 3

	// fmt.Println(cap(m1)) // invalid argument: m1 (variable of type map[int]string) for cap

	// example 7
	// m1 := map[int]string{1: "v1", 2: "v2"}
	// v3 := m1[3]
	// fmt.Println(v3) // ""

	// v3, ok := m1[3]
	// if !ok {
	// 	fmt.Println("key:3 not in map") // key:3 not in map
	// }

	// _, exists := m1[1]
	// if exists {
	// 	//  do something
	// 	fmt.Println(exists)	// true
	// }

	m1 := map[string]int{"k1": 1, "k2": 2}
	for k1, v1 := range m1 {
		fmt.Print(k1, ":", v1, "; ") // k1:1; k2:2;
	}

	for k, _ := range m1 {
		fmt.Println(k)
	}

	foo(m1)
	fmt.Println(m1) // map[k1:1 k2:2 new:101]
}

func foo(m map[string]int) {
	m["new"] = 101
}
